package com.example.administrator.basedemos.activity;

import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;

import com.chad.library.adapter.base.BaseQuickAdapter;
import com.example.administrator.basedemos.R;
import com.example.administrator.basedemos.adapter.MainAdapter;
import com.example.administrator.basedemos.base.BaseActivity;
import com.example.administrator.basedemos.okhttp.BaseCallBack;
import com.example.administrator.basedemos.inter.ProgressListener;
import com.example.administrator.basedemos.okhttp.ProgressResponse;
import com.example.administrator.basedemos.okhttp.SimpleOkhttpClient;
import com.example.administrator.basedemos.utils.LogUtil;
import com.example.administrator.basedemos.utils.TmtUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

import butterknife.BindView;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * 创建者     ZCL
 * 创建时间   2018/3/12 17:35
 * 描述	      ${TODO}
 * <p>
 * 更新者     $Author$
 * 更新时间   $Date$
 * 更新描述   ${TODO}
 */

public class Okhttp3Activity extends BaseActivity {
    private static final String TAG                                 = "Okhttp3Activity";
    private static final int    WRITE_EXTERNAL_STORAGE_REQUEST_CODE = 1;
    @BindView(R.id.recyclerview_mw)
    RecyclerView mOkhttpRecyclerview;
    @BindView(R.id.okhttp_processbar)
    ProgressBar  mOkhttpProcessbar;

    private ArrayList<String> mList;
    private OkHttpClient      mClient;
    private Handler           mHandler;
    private String url       = "http://dl.app.sogou.com/qq%e9%9f%b3%e4%b9%90.apk";
    String urlBd = "http://www.baidu.com/";
    String urlLogin = "http://www.baidu.com/bdorz/login";
    private String name      = "xztest.apk";
    private String nameinter = "xztestInter.apk";
    private Integer sdk;
    private Request request;
    private String  path;
    private int     osVersion;

    MediaType File_type = MediaType.parse("application/octet-stream");


    @Override
    public void initView() {
        osVersion = Integer.valueOf(Build.VERSION.SDK);
        path = Environment.getExternalStorageDirectory().getAbsolutePath();
        request = new Request.Builder().url(url).build();
        sdk = Integer.valueOf(Build.VERSION.SDK);
        mClient = new OkHttpClient();

        mHandler = new Handler(new Handler.Callback() {
            @Override
            public boolean handleMessage(Message message) {
                if (message.what == 1) {
                    int process = message.arg1;
                    LogUtil.util(TAG, "更新进度------------------:" + process);
                    mOkhttpProcessbar.setProgress(process);
                }
                return true;
            }
        });
    }

    @Override
    public void initData() {
        mList = new ArrayList<String>();
        mList.add( "get");
        mList.add( "josn");
        mList.add( "form");
        mList.add( "拦截器下载文件");
        mList.add( "download下载文件");
        mList.add( "上传文件到服务器");
        mList.add( "封装Get");
        mList.add( "封装form");
        mList.add( "封装Json");

        mOkhttpRecyclerview.setLayoutManager(new GridLayoutManager(this, 2));

        MainAdapter adapter = new MainAdapter(R.layout.main_item, mList);
        adapter.setSpanSizeLookup(new BaseQuickAdapter.SpanSizeLookup() {
            @Override
            public int getSpanSize(GridLayoutManager gridLayoutManager, int position) {
                //设置每行几个条目
                int count = setSpanSize(mList, position);
                return count;
            }
        });
        adapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                switch (position) {
                    case 0:
                        getOKhttp();
                        break;
                    case 1:
                        jsonOKhttp();
                        break;
                    case 2:
                        formOKhttp();
                        break;
                    case 3:
                        DownloadOKhttpInterceptors();
                        break;
                    case 4:
                        downloadOKhttp();
                        break;
                    case 5:
                        postAsynFile("/storage/emulated/0/xztest.apk");
                        break;
                    case 6:
                    case 7:
                    case 8:
                        SimpleOkhttpClient.newBuilder().url(urlBd)
                                .get().method("GET").build().enqueue(new BaseCallBack<String>() {
                            @Override
                            public void onSuccess(String s) {
                                LogUtil.util(TAG,"返回数据是------------------------------:"+s);
                            }
                        });
                        break;
                }
            }
        });
        //ALPHAIN：渐显；SCALEIN：缩放；SLIDEIN_BOTTOM：从下到上；
        //SLIDEIN_LIFT：从左到右；SLIDEIN_RIGHT：从右到左
        adapter.openLoadAnimation(BaseQuickAdapter.SLIDEIN_RIGHT);
        mOkhttpRecyclerview.setAdapter(adapter);
    }

    private int setSpanSize(ArrayList<String> list, int position) {
        if (list.get(position).length() > 8) {
            return 2;
        } else {
            return 1;
        }
    }

    private void setData(Response response) throws IOException {
        String body = "";
        boolean b = response.isSuccessful();
        //如果要操作界面一定要到主线程  因为这是异步
        if (b) {
            body = response.body().string();
            LogUtil.util(TAG, "返回数据成功----------:" + body);
        } else {
            LogUtil.util(TAG, "返回数据失败----------:" + body);
        }
        if (response != null) {
            //防止內存洩漏
            response.body().close();
        }
    }


    private void postAsynFile(String dir) {

        File file = new File(dir);
        if (file.exists()){
            Log.d(TAG,"文件存在-------:"+file.getAbsolutePath());
        }

        RequestBody fileBody = RequestBody.create(File_type, file);
        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("apk", name, fileBody)
                .build();
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();

        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.d(TAG, "上传text失败了" + e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.body()!=null)
                    response.body().close();
                LogUtil.util("上传text成功了", response.body().string());
            }
        });
    }

    private void DownloadOKhttpInterceptors() {

        OkHttpClient.Builder builder = new OkHttpClient().newBuilder().addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                //通過chain獲取response
                Response response = chain.proceed(chain.request());
                //因為要重新構建所以要newBuilder
                return response.newBuilder().body(new ProgressResponse(response.body(), new ProgressLis())).build();
            }
        });
        builder.build().newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtil.util(TAG, "拦截器失败------------:" + e.getLocalizedMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    LogUtil.util(TAG, "拦截器成功-----:");
                    writeFileInterceptor(response);
                } else
                    LogUtil.util(TAG, "拦截器失败-----:");

            }
        });
    }

    private void writeFileInterceptor(Response response) {
        getPermission(sdk);
        InputStream is = null;
        FileOutputStream fos = null;

        is = response.body().byteStream();
        File file = new File(path, nameinter);
        ioMethod(is, fos, file);
    }

    private void ioMethod(InputStream is, FileOutputStream fos, File file) {
        try {
            fos = new FileOutputStream(file);

            byte[] bytes = new byte[1024];
            while ((is.read(bytes)) != -1) {
                fos.write(bytes);
            }

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            closeIo(fos, is);
        }
    }

    private void getPermission(Integer sdk) {
        if (sdk >= 23) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                //申請授權
                ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case WRITE_EXTERNAL_STORAGE_REQUEST_CODE:
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "onRequestPermissionsResult: request write permission success!");
                    //处理依赖权限的代码

                } else {
                    Log.d(TAG, "onRequestPermissionsResult: request write permission fail!");
                    //请求失败，没有权限，不能运行依赖权限的代码
                }
                break;
        }
    }

    private void downloadOKhttp() {
        OkHttpClient client = new OkHttpClient();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtil.util(TAG, "下载apk失败----:" + e.getMessage() + "#######" + e.getLocalizedMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    writeFile(response);
                }
                response.body().close();
            }
        });
    }

    private void writeFile(Response response) {
        FileOutputStream fos = null;
        InputStream is = null;
        is = response.body().byteStream();

        getPermission(osVersion);

        writeFileNormal(response, fos, is);

    }

    private void writeFileNormal(Response response, FileOutputStream fos, InputStream is) {
        //先通过Environment（环境）的getExternalStorageState()方法来获取手机环境下的外置存储卡的状态，判断是否为挂载状态。
        String status = Environment.getExternalStorageState();
        checkSd(status);

        //绝对路径

        File file = new File(path, name);
        LogUtil.util(TAG, "path:" + file.getAbsolutePath());
        LogUtil.util(TAG, "file是否为存在------------------------------:" + file.exists());
        try {
            fos = new FileOutputStream(file);

            byte[] bytes = new byte[1024];

            int len = 0;
            long sum = 0;
            long totalSize = response.body().contentLength();

            LogUtil.util(TAG, "path:" + path + "------" + totalSize);

            while ((len = is.read(bytes)) != -1) {
                fos.write(bytes);
                sum += len;
                int process = (int) ((sum * 1.0f / totalSize) * 100);
                LogUtil.util(TAG, "下载--------:" + process);
                //通知更新
                Message message = mHandler.obtainMessage(1);
                message.arg1 = process;
                mHandler.sendMessageAtTime(message, 1000);
            }

        } catch (FileNotFoundException e) {
            LogUtil.util(TAG, "異常文件");
            e.printStackTrace();
        } catch (IOException e) {
            LogUtil.util(TAG, "異常");
            e.printStackTrace();
        } finally {
            closeIo(fos, is);
        }
    }

    private void closeIo(FileOutputStream fos, InputStream is) {
        try {
            if (is != null) {
                is.close();
            }
            if (fos != null) {
                fos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void checkSd(String status) {
        if (status.equalsIgnoreCase(Environment.MEDIA_MOUNTED)) {
            LogUtil.util(TAG, "SD卡存在，此时SD是可读写的");
            // 此时SD是可读写的
        } else if (status.equalsIgnoreCase(Environment.MEDIA_MOUNTED_READ_ONLY)) {
            LogUtil.util(TAG, "虽然SD卡存在，但是为只读状态");
        } else if (status.equalsIgnoreCase(Environment.MEDIA_REMOVED)) {
            LogUtil.util(TAG, "SD不存在");
        } else if (status.equalsIgnoreCase(Environment.MEDIA_SHARED)) {
            LogUtil.util(TAG, "虽然SD卡存在，但是正与PC等相连接");
        } else if (status.equalsIgnoreCase(Environment.MEDIA_BAD_REMOVAL)) {
            LogUtil.util(TAG, "SD卡在挂载状态下被错误取出");
        } else if (status.equalsIgnoreCase(Environment.MEDIA_CHECKING)) {
            LogUtil.util(TAG, "正在检查SD卡");
        } else if (status.equalsIgnoreCase(Environment.MEDIA_NOFS)) {
            LogUtil.util(TAG, "虽然SD卡存在，但其文件系统不被支持");
        } else if (status.equalsIgnoreCase(Environment.MEDIA_UNMOUNTABLE)) {
            LogUtil.util(TAG, "虽然SD卡存在，但是无法被挂载");
        } else if (status.equalsIgnoreCase(Environment.MEDIA_UNMOUNTED)) {
            LogUtil.util(TAG, "虽然SD卡存在，但是未被挂载");
        } else {
            LogUtil.util(TAG, "其他原因");
        }
    }

    private void formOKhttp() {
        FormBody body = new FormBody.Builder()
                .add("username", "zhang123")
                .add("password", "123456")
                .build();
        Request request = new Request.Builder()
                .post(body)
                .url(urlLogin)
                .build();
        OkhttpGo(request);
    }

    private void jsonOKhttp() {
        String url = "http://www.baidu.com/bdorz/login/json";
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("username", "zhang123");
            jsonObject.put("username", "zhang123");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        String jsonParams = jsonObject.toString();
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json;charset =utf-8"), jsonParams);
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        OkhttpGo(request);

    }

    private void getOKhttp() {
        Request request = new Request.Builder().get().url(urlBd).build();
        //execute 同步請求  enque 一部请求
        OkhttpGo(request);
    }

    private void OkhttpGo(Request request) {
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                LogUtil.util(TAG, "请求失败-----" + e.getMessage() + "---------" + e.getLocalizedMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                setData(response);
            }
        });
    }

    @Override
    public int setLayoutId() {
        return R.layout.activity_okhttp;
    }

    private class ProgressLis implements ProgressListener {
        @Override
        public void progressUpdata(final int pro) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mOkhttpProcessbar.setProgress(pro);
                }
            });
        }

        @Override
        public void ProgressDone(long toalSize) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    TmtUtils.midToast(Okhttp3Activity.this, "下载完成!");
                }
            });
        }
    }
}
